#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__author__ = "Administrator"
__name__="multiprocess_communication"
__date__="2016/8/1"
__time__="16:57"
"""
from multiprocessing import Process
from multiprocessing import Queue   # 将原生的queue进行了包装
import threading
from multiprocessing import Lock
import time
"""
def run(info_list,n):
    info_list.append(n)
    print info_list

info = []

# 多进程
if __name__ == '__main__':
    for i in range(10):
        p = Process(target=run,args=[info,i])
        p.start()
# 每个进程都会读一个空的列表，将数字加到各自了列表
# 一个列表赋给多个进程，每个进程都会克隆列表
# 线程是将数字都会加到一个列表中

# 多线程
print '-----threading-----'
for i in range(10):
    p = threading.Thread(target=run,args=[info,i])
    p.start()
"""

"""
# 进程间内存共享法一 -- queue
# 进程间通信通过queue实现。
def f(q,n):
    q.put([n, 'hello'])
if __name__ == '__main__':
    q = Queue()
    for i in range(5):
        p = Process(target=f, args=(q,i))
        p.start()
    while True:
        print q.get()
"""
"""
# 进程间内存共享法二 -- 进程锁
# a clone of threading.lock
# 用处：多个进程同时输出到屏幕，涉及到屏幕抢占。其他情况下数据本来就是独立的，用不到lock。
def f(l,i):
    l.acquire()
    print 'hello world',i
    l.release()
if __name__ == '__main__':
    lock = Lock()
    for num in range(10):
        Process(target=f,args=(lock,num)).start()
"""
"""
# 进程间内存共享法三 -- value array :对象是数字和列表
# 内存共享
from multiprocessing import Process,Value,Array

def f(n,a,raw):
    n.value = 3.1314927
    for i in range(5):
        a[i] = -a[i]
    raw.append(9999)
    print raw

if __name__ == '__main__':
    num = Value('d',0.0)
    arr = Array('i',range(10))  # 封装后的列表，父进程和子进程共用一份。
    raw_list = range(10)    # 原生列表
    print num.value
    print arr[:]
# 上面5行在父进程中执行

    p = Process(target=f,args=(num,arr,raw_list))
    p.start()
    p.join()
# 主进程生成子进程，子进程调用函数f，将value值从0.0改为3.1415927 ，将i的值改为负数；重点：由于raw_list是原生的列表，子进程和父进程的raw_list是相互独立的，函数f中append只是修改子进程的raw_list值，父进程的不改变；print raw 显示的是子进程的值，print raw_list显示的是父进程的值。
    print num.value
    print arr[:]
    print raw_list
"""

#   进程间内存共享法四 -- manager
# support types list: dict ,namespace,lock,rlock,semaphore（信号）,boundedseamaphore,condition,event,quue,value and array.
# 线程内存共享是真正的内存共享，进程内存共享是通过第三方通道，一个桥梁来实现。
from multiprocessing import Process,Manager

def f(d,l):
    d[1] = '1'
    d['2']= 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    manager = Manager()
    d = manager.dict()
    l = manager.list(range(10))

    p = Process(target=f,args=(d,l))
    p.start()
    p.join()

    print d
    print l
# 父进程的d l 都是空值，执行结果显示表明，子进程修改了父进程的值。
# manager本身就是线程安全的，一份数据只会给一个进程。
# a single manager can be shared by processes on different computers over a network, howerer, slower than using shared memory

# 优先使用queue和manager























